Groovy, যা Java Virtual Machine (JVM) এর উপর রান করে, Java এর মতো Concurrency (একাধিক থ্রেডের মাধ্যমে একযোগে কাজ) এবং Thread-Safety এর বিষয়গুলোকে সমর্থন করে। যখন একাধিক থ্রেড একে অপরের সাথে ডেটা শেয়ার করে, তখন সেগুলির মধ্যে সঠিক সমন্বয় বজায় রাখাটা গুরুত্বপূর্ণ, যাতে ডেটার কোনো Race Conditions বা অবাঞ্ছিত পরিবর্তন না ঘটে। এই সমস্যা সমাধানে Synchronization এবং Thread-Safety টেকনিকস ব্যবহৃত হয়।
Groovy তে, Java এর synchronized
ব্লক এবং অন্যান্য থ্রেড-সেফ মেকানিজমের পাশাপাশি Groovy এর সহজ সিনট্যাক্স এবং টুলস ব্যবহার করে আপনি কনকারেন্সি এবং থ্রেড-সেফ প্রোগ্রাম তৈরি করতে পারেন।
এখানে Synchronization এবং Thread-Safety এর টেকনিকস আলোচনা করা হলো।
Synchronization হল একটি পদ্ধতি যার মাধ্যমে আপনি নিশ্চিত করেন যে একাধিক থ্রেড একই সময়ে একটি ক্রিটিকাল সেকশনে প্রবেশ করতে পারে না। যখন একাধিক থ্রেড একসাথে একটি ডেটা বা মেথড অ্যাক্সেস করে, তখন এটি সঠিকভাবে কাজ না করতে পারে (এটা Race Condition তৈরি করতে পারে)। Synchronization এর মাধ্যমে এই সমস্যা এড়ানো হয়।
Groovy তে synchronized
কিওয়ার্ড ব্যবহার করে আপনি একটি মেথডকে সিঙ্ক্রোনাইজ করতে পারেন, যাতে একাধিক থ্রেড একই মেথড একসাথে এক্সিকিউট না করতে পারে।
class Counter {
private int count = 0
// Synchronized method
synchronized void increment() {
count++
}
int getCount() {
return count
}
}
def counter = new Counter()
// Simulating two threads accessing increment method
def thread1 = new Thread({ counter.increment() })
def thread2 = new Thread({ counter.increment() })
thread1.start()
thread2.start()
thread1.join()
thread2.join()
println counter.getCount() // Output: 2
এখানে, increment()
মেথড সিঙ্ক্রোনাইজ করা হয়েছে, যাতে একসাথে একাধিক থ্রেড একই সময়ে count
এর মান পরিবর্তন করতে না পারে।
আপনি শুধু নির্দিষ্ট অংশের কোডকে সিঙ্ক্রোনাইজ করতে চান, তবে synchronized
ব্লক ব্যবহার করতে পারেন। এটি থ্রেড-সেফ কোড ব্লক তৈরি করতে সহায়তা করে।
class Counter {
private int count = 0
void increment() {
synchronized(this) {
count++
}
}
int getCount() {
return count
}
}
def counter = new Counter()
// Simulating two threads accessing increment method
def thread1 = new Thread({ counter.increment() })
def thread2 = new Thread({ counter.increment() })
thread1.start()
thread2.start()
thread1.join()
thread2.join()
println counter.getCount() // Output: 2
এখানে, synchronized(this)
ব্লকটি শুধুমাত্র count
পরিবর্তন করার অংশকে সিঙ্ক্রোনাইজ করেছে, যাতে দুটি থ্রেড একসাথে এই অংশে প্রবেশ না করতে পারে।
Thread-Safety নিশ্চিত করার জন্য বিভিন্ন টেকনিক ব্যবহার করা হয়, যাতে একাধিক থ্রেড একসাথে ডেটা অ্যাক্সেসের সময় কোনো সমস্যা না ঘটে।
Groovy তে volatile
ভেরিয়েবল ব্যবহার করা হয় যেগুলি একাধিক থ্রেডের মধ্যে শেয়ার করা হয়। এটি নিশ্চিত করে যে ভেরিয়েবলটি কোনো একটি থ্রেড দ্বারা পরিবর্তন হলে তা অন্য সমস্ত থ্রেডের কাছে সঠিকভাবে আপডেট হবে।
class SharedResource {
volatile boolean flag = false
void setFlag(boolean value) {
flag = value
}
boolean getFlag() {
return flag
}
}
def resource = new SharedResource()
// Thread 1
def thread1 = new Thread({
resource.setFlag(true)
})
// Thread 2
def thread2 = new Thread({
while (!resource.getFlag()) {
// Waiting for flag to become true
}
println "Flag was set to true!"
})
thread1.start()
thread2.start()
thread1.join()
thread2.join()
এখানে, volatile
ভেরিয়েবল flag
ব্যবহার করা হয়েছে, যাতে যখন থ্রেড একটি ভেরিয়েবল পরিবর্তন করে, সেটি অন্য থ্রেডে সঠিকভাবে প্রতিফলিত হয়।
Groovy তে আপনি Java এর ReentrantLock
ব্যবহার করে লকিং মেকানিজমও প্রয়োগ করতে পারেন। এটি সিঙ্ক্রোনাইজেশনের চেয়ে আরও বেশি নিয়ন্ত্রণ দেয়।
import java.util.concurrent.locks.ReentrantLock
class Counter {
private int count = 0
private final ReentrantLock lock = new ReentrantLock()
void increment() {
lock.lock()
try {
count++
} finally {
lock.unlock()
}
}
int getCount() {
return count
}
}
def counter = new Counter()
// Simulating two threads accessing increment method
def thread1 = new Thread({ counter.increment() })
def thread2 = new Thread({ counter.increment() })
thread1.start()
thread2.start()
thread1.join()
thread2.join()
println counter.getCount() // Output: 2
এখানে, ReentrantLock
ব্যবহার করে increment()
মেথডের উপরে লক প্রয়োগ করা হয়েছে। এটি কোডের অংশের উপর আরও নিয়ন্ত্রিত সিঙ্ক্রোনাইজেশন সরবরাহ করে।
Groovy তে, atomic variables ব্যবহার করা যেতে পারে যখন একাধিক থ্রেড একই ভেরিয়েবল অ্যাক্সেস করে। Java এর AtomicInteger
বা AtomicReference
Groovy তে সরাসরি ব্যবহৃত হতে পারে। এটি lock-free অপারেশন প্রদান করে।
import java.util.concurrent.atomic.AtomicInteger
class Counter {
private final AtomicInteger count = new AtomicInteger(0)
void increment() {
count.incrementAndGet()
}
int getCount() {
return count.get()
}
}
def counter = new Counter()
// Simulating two threads accessing increment method
def thread1 = new Thread({ counter.increment() })
def thread2 = new Thread({ counter.increment() })
thread1.start()
thread2.start()
thread1.join()
thread2.join()
println counter.getCount() // Output: 2
এখানে, AtomicInteger
ব্যবহার করা হয়েছে যাতে atomic operations নিশ্চিত করা যায় এবং থ্রেড-সেফভাবে ভেরিয়েবলটি ইনক্রিমেন্ট করা যায়।
Groovy তে Threading সহজ করার জন্য কিছু বিল্ট-ইন বৈশিষ্ট্য রয়েছে, যেমন GPars
(Groovy Parallel Systems) লাইব্রেরি, যা থ্রেড পুল, ফিউচারস এবং পারালাল প্রসেসিংয়ের জন্য ব্যবহৃত হয়।
Groovy তে GPars লাইব্রেরি ব্যবহার করে পারালাল থ্রেডিং সহজে করা যায়।
@Grab(group='org.codehaus.groovy', module='groovy-all', version='2.4.7')
import groovyx.gpars.GParsPool
GParsPool.withPool {
(1..5).eachParallel { num ->
println "Thread $num is running"
}
}
এখানে, eachParallel
মেথডের মাধ্যমে পাঁচটি থ্রেড একসাথে রান করা হয়েছে।
Groovy তে Synchronization এবং Thread-Safety নিশ্চিত করার জন্য বিভিন্ন টেকনিক ব্যবহৃত হয়:
volatile
, ReentrantLock
, এবং Atomic
ক্লাস ব্যবহার করা যেতে পারে।Groovy তে এই টেকনিকসের মাধ্যমে আপনি সহজেই থ্রেড-সেফ প্রোগ্রাম তৈরি করতে পারেন এবং একাধিক থ্রেডের মধ্যে সঠিক সমন্বয় বজায় রাখতে পারেন।
common.read_more